package com.powergisol.gis.util;

import com.powergisol.gis.dto.RDto;

import javax.script.*;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * Created By marc
 * Date: 2020/9/3  16:39
 * Description:x\y坐标经纬度转换
 */
public class XyChangeUtil {

    private static Compilable compilable;

    private static Bindings bindings;

    /**
     *
     * @param x  经度-180->180
     * @param y 纬度-90->90
     * @param script 公式
     * @return
     */
    public static BigDecimal change(Double x, Double y, String script) {
        BigDecimal num = BigDecimal.ZERO;
       if(null == compilable){
           ScriptEngine engine = new ScriptEngineManager().getEngineByName("javascript");
           compilable = (Compilable) engine;
           bindings = engine.createBindings(); //Local级别的Binding
       }

        CompiledScript JSFunction = null; //解析编译脚本函数
        try {
            JSFunction = compilable.compile(script);
            bindings.put("x", x);
            bindings.put("y", y);
            Object result = JSFunction.eval(bindings);
            num =  new BigDecimal(result.toString()).setScale(6, BigDecimal.ROUND_HALF_UP);
        } catch (ScriptException e) {
           // System.out.println("公式计算异常");
        }
        return num;
    }
    public static BigDecimal changeBybigDecimal(BigDecimal x, BigDecimal y, String script) {
       if(null == compilable){
           ScriptEngine engine = new ScriptEngineManager().getEngineByName("javascript");
           compilable = (Compilable) engine;
           bindings = engine.createBindings(); //Local级别的Binding
       }

        CompiledScript JSFunction = null; //解析编译脚本函数
        try {
            JSFunction = compilable.compile(script);
            bindings.put("x", x);
            bindings.put("y", y);
            Object result = JSFunction.eval(bindings);
            return new BigDecimal(result.toString()).setScale(6, BigDecimal.ROUND_HALF_UP);
        } catch (ScriptException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static BigDecimal newChangeBybigDecimal(BigDecimal x, BigDecimal y, String script) {
        if(null == compilable){
            ScriptEngine engine = new ScriptEngineManager().getEngineByName("javascript");
            compilable = (Compilable) engine;
            bindings = engine.createBindings(); //Local级别的Binding
        }

        CompiledScript JSFunction = null; //解析编译脚本函数
        try {
            JSFunction = compilable.compile(script);
            bindings.put("x", x);
            bindings.put("y", y);
            Object result = JSFunction.eval(bindings);
            return new BigDecimal(result.toString()).setScale(10, BigDecimal.ROUND_DOWN);
        } catch (ScriptException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static Double changeDouble(Double x, Double y, String script) {
        if(null == compilable){
            ScriptEngine engine = new ScriptEngineManager().getEngineByName("javascript");
            compilable = (Compilable) engine;
            bindings = engine.createBindings(); //Local级别的Binding
        }

        CompiledScript JSFunction = null; //解析编译脚本函数
        try {
            JSFunction = compilable.compile(script);
            bindings.put("x", x);
            bindings.put("y", y);
            Object result = JSFunction.eval(bindings);
            return Double.valueOf(result.toString());
        } catch (ScriptException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static BigDecimal changey(BigDecimal x, BigDecimal y) {
        BigDecimal x1 = x.multiply(new BigDecimal("9.02593")).multiply(new BigDecimal("0.000001")).setScale(8,BigDecimal.ROUND_HALF_UP);
        BigDecimal y1 = y.multiply(new BigDecimal("1.46935")).multiply(new BigDecimal("0.0000001")).setScale(8,BigDecimal.ROUND_HALF_UP);

        return x1.add(y1).add(new BigDecimal("22.35169056")).setScale(6,BigDecimal.ROUND_HALF_UP);
    }

    public static BigDecimal changex(BigDecimal x, BigDecimal y) {
        BigDecimal x1 = x.multiply(new BigDecimal("-1.62587")).multiply(new BigDecimal("0.0000001")).setScale(8,BigDecimal.ROUND_HALF_UP);
        BigDecimal y1 = y.multiply(new BigDecimal("9.72822")).multiply(new BigDecimal("0.000001")).setScale(8,BigDecimal.ROUND_HALF_UP);
        return x1.add(y1).add(new BigDecimal("112.9402592")).setScale(6,BigDecimal.ROUND_HALF_UP);
    }

    //计算坐标k值
    public static RDto getK(Double x1, Double y1, Double x2, Double y2) {
        Double k = (y2-y1)/(x2-x1);

        Double x  =1 + k*k;
        Double y = 1+1/(k*k);

        RDto dto = new RDto();
        dto.setX(x);
        dto.setY(y);
        return dto;
    }

    //计算坐标k值
    public static RDto getK(Double x, Double y, Double distance,Double x1, Double y1) {
        Double X = distance/x - x1;
        Double Y = distance/y - y1;

        RDto dto = new RDto();
        dto.setX(X);
        dto.setY(Y);
        return dto;
    }

    public static void main(String[] args) {
        //14.666243303962625 : 1.0731729984428158
        List<RDto> list = new ArrayList<>();
        Double y0 = 94963.01;
        Double x0 = 18628.31;

        RDto dto = new RDto();
        dto.setOx(x0);
        dto.setOy(y0);
        dto.setX(change(x0,y0,"x * (-1.62587) * 0.0000001 + y * 9.72822 * 0.000001 + 112.9402592").doubleValue());
        dto.setY(change(x0,y0,"x * 9.02593 * 0.000001 + y * 1.46935 * 0.0000001 + 22.35169056").doubleValue());
        dto.setType(1);

        //横向数量
        Double yh = (95030.92-94963.01)*(95030.92-94963.01);
        Double xh = (18646.68-18628.31)*(18646.68-18628.31);
        Double lengthh = Math.sqrt(yh+xh);
        int n = (int)Math.ceil((lengthh - 2*(4+5*3+2*2))/3)+(1+5+2)*2;

        //纵向数量
        Double yz = (95140.48-94963.01)*(95140.48-94963.01);
        Double xz = (17966.70-18628.31)*(17966.70-18628.31);
        Double lengthz = Math.sqrt(yz+xz);
        int m = (int)Math.ceil(lengthz/5);

        Double ox = 0d;
        Double oy = 0d;
        for (int i = 0; i < n; i++) {
            RDto dto1 = new RDto();
            if(i==0){
                x0 = x0;
                y0 = y0;
            }else if(i == 1 || i == n){//4m距离
                x0 = 4/14.666243303962625 + x0;
                y0 = 4/1.0731729984428158 + y0;
            }else if(i==8 || i == 9 || i ==(n-6)||i==(n-7)){//2m距离
                x0 = 2/14.666243303962625 + x0;
                y0 = 2/1.0731729984428158 + y0;
            }else{//3m距离
                x0 = 3/14.666243303962625 + x0;
                y0 = 3/1.0731729984428158 + y0;
            }
            dto1.setOx(x0);
            dto1.setOy(y0);
            dto1.setX(change(x0,y0,"x * (-1.62587) * 0.0000001 + y * 9.72822 * 0.000001 + 112.9402592").doubleValue());
            dto1.setY(change(x0,y0,"x * 9.02593 * 0.000001 + y * 1.46935 * 0.0000001 + 22.35169056").doubleValue());
            dto1.setType(1);
            list.add(dto1);
            System.out.println("dto1="+dto1.toString());
            for (int j = 0; j < m; j++) {
                RDto dto2 = new RDto();
                if(j == 0){
                    ox = x0;
                    oy = y0;
                }else{
                    ox = j*5/14.666243303962625 + x0;
                    oy = j*5/1.0731729984428158 + y0;
                }
                dto2.setOx(ox);
                dto2.setOy(oy);
                dto2.setX(change(ox,oy,"x * (-1.62587) * 0.0000001 + y * 9.72822 * 0.000001 + 112.9402592").doubleValue());
                dto2.setY(change(ox,oy,"x * 9.02593 * 0.000001 + y * 1.46935 * 0.0000001 + 22.35169056").doubleValue());
                dto2.setType(1);
                list.add(dto2);
                System.out.println("dto2="+dto2.toString());
            }
        }
        System.out.println(list.size());
    }

}
